package com.tbvtc.agriculturalcreditchainserver2025.utils.Pest;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tbvtc.agriculturalcreditchainserver2025.entity.Crop;
import com.tbvtc.agriculturalcreditchainserver2025.entity.CropFertilizerCheck;
import com.tbvtc.agriculturalcreditchainserver2025.entity.PesticideReportResult;
import com.tbvtc.agriculturalcreditchainserver2025.service.ICropFertilizerCheckService;
import com.tbvtc.agriculturalcreditchainserver2025.service.ICropService;
import com.tbvtc.agriculturalcreditchainserver2025.service.IpfsService;
import com.tbvtc.agriculturalcreditchainserver2025.utils.RUtils;
import com.tbvtc.agriculturalcreditchainserver2025.utils.Result;
import com.tbvtc.agriculturalcreditchainserver2025.utils.huawei.HwCloudIot;
import com.tbvtc.agriculturalcreditchainserver2025.vo.ConsumerVo.CropFertilizerCheckItems;
import com.tbvtc.agriculturalcreditchainserver2025.vo.ConsumerVo.CropFertilizerCheckVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.annotation.RegEx;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 农药检测报告生成工具类
 */
@Slf4j
@Component
public class PesticideReportGenerator {


    @Resource
    private ICropService cropService;
    @Resource
    private ICropFertilizerCheckService cropFertilizerCheckService;
    @Value("${html.path}")
    private File reportTemplate;
    @Resource
    private IpfsService ipfsService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 生成检测报告HTML文件
     *
     * @param cropFertilizerCheckVos 后端数据集合
     * @param outputPath             输出文件路径
     */
    public void generateReport(List<CropFertilizerCheckVo> cropFertilizerCheckVos, String outputPath) {
        // 1. 构建HTML内容
        StringBuilder htmlBuilder = new StringBuilder();

        // 2. 添加HTML头部和样式
        htmlBuilder.append("<!DOCTYPE html>\n")
                .append("<html lang=\"zh-CN\">\n")
                .append("<head>\n")
                .append("    <meta charset=\"UTF-8\">\n")
                .append("    <title>农药使用检验检测报告</title>\n")
                .append("    <style>\n")
                .append("        body { font-family: \"SimSun\", \"宋体\", serif; line-height: 1.6; margin: 40px; }\n")
                .append("        .header { text-align: center; margin-bottom: 30px; }\n")
                .append("        .title { font-size: 24px; font-weight: bold; margin: 10px 0; }\n")
                .append("        .subtitle { font-size: 16px; margin: 5px 0 20px; }\n")
                .append("        .report-info { display: flex; justify-content: space-between; margin-bottom: 20px; font-size: 14px; }\n")
                .append("        table { width: 100%; border-collapse: collapse; margin-bottom: 30px; }\n")
                .append("        th, td { border: 1px solid #000; padding: 8px 10px; text-align: left; font-size: 14px; }\n")
                .append("        th { background-color: white; font-weight: bold; }\n")
                .append("        .section-title { font-size: 16px; font-weight: bold; margin: 20px 0 10px; padding-left: 5px; border-left: 3px solid #333; }\n")
                .append("        .conclusion { border: 1px solid #000; padding: 15px; margin: 20px 0; }\n")
                .append("        .signature { display: flex; justify-content: space-between; margin: 40px 0; }\n")
                .append("        .stamp { text-align: right; margin: 30px 0; color: white; font-style: italic; font-size: 18px; }\n")
                .append("        .footer { font-size: 12px; margin-top: 50px; line-height: 1.8; }\n")
                .append("        .loading { text-align: center; padding: 50px; font-size: 16px; }\n")
                .append("        .error { text-align: center; padding: 50px; color: white; font-size: 16px; }\n")
                .append("    </style>\n")
                .append("</head>\n")
                .append("<body>\n");

        // 3. 隐藏加载和错误状态（直接渲染数据，无需JS加载）
        htmlBuilder.append("    <div class=\"loading\" id=\"loading\" style=\"display: none;\">正在加载检测报告...</div>\n")
                .append("    <div class=\"error\" id=\"error\" style=\"display: none;\">报告加载失败，请稍后重试</div>\n")
                .append("    <div id=\"reportContent\">\n");

        // 4. 生成报告头部
        String reportNo = "NYJC" + DateUtil.format(DateUtil.date(), "yyyyMMdd") + IdUtil.fastSimpleUUID().substring(0, 3).toUpperCase();
        htmlBuilder.append("        <div class=\"header\">\n")
                .append("            <div style=\"display: flex; align-items: center; justify-content: center;\">\n")
                .append("                <div style=\"width: 50px; height: 50px; background-color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; margin-right: 15px;\">检</div>\n")
                .append("                <div>\n")
                .append("                    <div class=\"title\">检验检测报告</div>\n")
                .append("                    <div class=\"subtitle\">Inspection Report</div>\n")
                .append("                </div>\n")
                .append("            </div>\n")
                .append("            <div class=\"report-info\">\n")
                .append("                <div>No: ").append(reportNo).append("</div>\n")
                .append("            </div>\n")
                .append("        </div>\n");

        // 5. 生成阶段内容（核心：渲染cropFertilizerCheckVos数据）
        htmlBuilder.append("        <div id=\"stageContainer\">\n");
        for (CropFertilizerCheckVo stage : cropFertilizerCheckVos) {
            // 阶段标题
            htmlBuilder.append("            <div class=\"section-title\">").append(stage.getStageType()).append("农药使用明细</div>\n");

            // 阶段基本信息表格
            String cropName = stage.getCropName() != null ? stage.getCropName() : "未知作物";
            String firstCheckTime = stage.getCropFertilizerCheckItems() != null && !stage.getCropFertilizerCheckItems().isEmpty()
                    ? DateUtil.format(DateUtil.parse(String.valueOf(stage.getCropFertilizerCheckItems().get(0).getCreateTime())), "yyyy-MM-dd")
                    : "未知日期";
            htmlBuilder.append("            <table>\n")
                    .append("                <tr>\n")
                    .append("                    <th>农作物名称</th>\n")
                    .append("                    <td colspan=\"3\">").append(cropName).append("</td>\n")
                    .append("                    <th>阶段类型</th>\n")
                    .append("                    <td colspan=\"3\">").append(stage.getStageType()).append("</td>\n")
                    .append("                </tr>\n")
                    .append("                <tr>\n")
                    .append("                    <th>检测日期</th>\n")
                    .append("                    <td colspan=\"3\">").append(firstCheckTime).append("</td>\n")
                    .append("                    <th>检测类别</th>\n")
                    .append("                    <td colspan=\"3\">农药使用合规性检查</td>\n")
                    .append("                </tr>\n")
                    .append("            </table>\n");

            // 农药明细表格（遍历每个检测项）
            if (stage.getCropFertilizerCheckItems() != null) {
                for (CropFertilizerCheckItems item : stage.getCropFertilizerCheckItems()) {
                    htmlBuilder.append("            <table>\n")
                            .append("                <tr>\n")
                            .append("                    <th>农药类型</th>\n")
                            .append("                    <th>标准用量</th>\n")
                            .append("                    <th>实际用量</th>\n")
                            .append("                    <th>单次是否合格</th>\n")
                            .append("                    <th>参考依据</th>\n")
                            .append("                    <th>AI结论</th>\n")
                            .append("                </tr>\n")
                            .append("                <tr>\n")
                            .append("                    <td>").append(item.getFertilizerType()).append("</td>\n")
                            .append("                    <td>").append(item.getStandardDosage()).append("</td>\n")
                            .append("                    <td>").append(item.getFarmerDosage()).append("</td>\n")
                            .append(" <td>").append(item.getIsQualified() ? "<span style='color: green;'>是（合格）</span>" : "<span style='color: red;'>否（不合格）</span>").append("</td>\n")
                            .append("                    <td>").append(item.getReferenceBasis()).append("</td>\n")
                            .append("                    <td>").append(item.getAiSuggestion().replace("\n", "<br>")).append("</td>\n")
                            .append("                </tr>\n")
                            .append("            </table>\n");
                }
            }
        }
        htmlBuilder.append("        </div>\n"); // 关闭stageContainer

        // 6. 生成综合结论
        long unqualifiedCount = cropFertilizerCheckVos.stream()
                .filter(stage -> !stage.getIsQualified())
                .count();
        String conclusion = unqualifiedCount == 0
                ? "本次检测中，所有阶段农药使用均符合相关标准，整体判定为<span style=\"font-weight: bold; color: green;\">合格</span>。"
                : "存在" + unqualifiedCount + "个阶段农药使用不合格项，需按AI建议调整；其余阶段使用符合标准。";
        String issueDate = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
        htmlBuilder.append("        <div class=\"conclusion\">\n")
                .append("            <div style=\"font-weight: bold; margin-bottom: 10px;\">综合判定结论</div>\n")
                .append("            <div id=\"conclusionText\">").append(conclusion).append("</div>\n")
                .append("            <div style=\"margin-top: 15px;\">签发日期：<span id=\"issueDate\">").append(issueDate).append("</span></div>\n")
                .append("        </div>\n");

        // 7. 生成备注、签名和页脚
        htmlBuilder.append("        <table>\n")
                .append("            <tr>\n")
                .append("                <th>备注</th>\n")
                .append("                <td>1. 检测数据基于委托方提供的农药使用记录；<br>2. AI建议仅供参考，实际操作请结合农技指导。</td>\n")
                .append("            </tr>\n")
                .append("        </table>\n")
                .append("        <div class=\"footer\">\n")
                .append("            地址：天津渤海职业技术学院<br>\n")
                .append("            电话：13174811957<br>\n")
                .append("            邮箱：3153966538@qq.com\n")
                .append("        </div>\n")
                .append("    </div>\n") // 关闭reportContent
                .append("</body>\n")
                .append("</html>");

        // 8. 写入文件（使用Hutool工具类简化IO操作，也可替换为原生Java IO）
        FileUtil.writeString(htmlBuilder.toString(), new File(outputPath), StandardCharsets.UTF_8);
        //删除
        System.out.println("报告生成成功，路径：" + outputPath);
    }

    public void getDetectionReport(Integer cropId) {
        Crop crop = cropService.getById(cropId);
        List<CropFertilizerCheck> cropFertilizerChecks = cropFertilizerCheckService.list(new LambdaQueryWrapper<CropFertilizerCheck>()
                .eq(CropFertilizerCheck::getCropName, crop.getName())
        );
        List<CropFertilizerCheckVo> cropFertilizerCheckVos = new ArrayList<>();
        Map<String, List<CropFertilizerCheck>> collect = cropFertilizerChecks.stream().collect(Collectors.groupingBy(CropFertilizerCheck::getStageType));
        collect.entrySet().forEach(entry -> {
            CropFertilizerCheckVo cropFertilizerCheckVo = new CropFertilizerCheckVo();
            cropFertilizerCheckVo.setStageType(entry.getKey());
            cropFertilizerCheckVo.setCropName(crop.getName());
            List<CropFertilizerCheckItems> cropFertilizerCheckItems = BeanUtil.copyToList(entry.getValue(), CropFertilizerCheckItems.class);
            cropFertilizerCheckVo.setCropFertilizerCheckItems(cropFertilizerCheckItems);
            cropFertilizerCheckVo.setIsQualified(true);
            cropFertilizerCheckItems.stream().forEach(cropFertilizerCheckItem -> {
                if (!cropFertilizerCheckItem.getIsQualified()) {
                    cropFertilizerCheckVo.setIsQualified(false);
                }
            });
            cropFertilizerCheckVos.add(cropFertilizerCheckVo);
        });
        generateReport(cropFertilizerCheckVos, reportTemplate.getPath());
        File file = new File(reportTemplate.getPath());
        // 创建WebClient时直接配置缓冲区大小（示例设为10MB）
        WebClient webClient = WebClient.builder()
                .codecs(configurer -> configurer.defaultCodecs()
                        .maxInMemorySize(10 * 1024 * 1024)) // 关键配置：10MB缓冲区
                .build();

        MultipartBodyBuilder builder = new MultipartBodyBuilder();
        builder.part("html_file", new FileSystemResource(file)); // 添加文件部分
        /**
         * 将生成的文字报告的html文件转为图片
         */
        Mono<PesticideReportResult> pesticideReportResultMono = webClient.post()
                .uri("http://localhost:8000/html2img")
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(builder.build()))
                .retrieve()
                .bodyToMono(PesticideReportResult.class)
                // 建议添加错误处理，捕获可能的异常（包括缓冲区问题、超时等）
                .onErrorResume(e -> {
                    log.error("调用html2img接口失败", e);
                    return Mono.error(new RuntimeException("生成报告结果失败", e));
                });

        pesticideReportResultMono.subscribe(pesticideReportResult -> {
            try {
                byte[] bytes = Base64.getDecoder().decode(pesticideReportResult.getBase64());
                String hash = ipfsService.uploadToIpfs(bytes);
                stringRedisTemplate.opsForValue().set("pesticideReport:" + cropId, hash);
                log.info("生成成功，hash：{}", hash);
                FileUtil.del(reportTemplate.getPath());
                log.info("删除成功路径为{}", reportTemplate.getPath());
            } catch (IOException e) {
                System.out.println(e.getMessage());
                throw new RuntimeException(e);
            }
        });
    }
}